/**
 * @file EpollEvent.h
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-04-05
 *
 * @copyright Copyright (c) 2022
 *
 */

#pragma once

#include "../utils/MutexLock.h"
#include "../utils/Noncopyable.h"
#include "TcpConnection.h"
#include <functional>
#include <map>
#include <sys/epoll.h>
#include <vector>

namespace wd
{
class EpollEvent : Noncopyable
{
  public:
    typedef TcpConnection::TcpConnectionCallback EpollCallback;
    typedef std::function<void()> Functor;

    EpollEvent(int listenfd);
    ~EpollEvent();

    void loop();
    void unloop();
    void runInLoop(const Functor &cb);
    void doPendingFunctors();

    void wakeup();
    void handleRead();

    void setConnectionCallback(EpollCallback cb);
    void setMessageCallback(EpollCallback cb);
    void setCloseCallback(EpollCallback cb);

  private:
    void waitEpollfd();
    void handleConnection();
    void handleMessage(int peerfd);

  private:
    int epollfd_;
    int listenfd_;
    int wakeupfd_;
    bool isLooping_;

    MutexLock mutex_;
    std::vector<Functor> pendingFunctors_;

    typedef std::vector<struct epoll_event> EventList;
    EventList eventsList_;

    typedef std::map<int, TcpConnectionPtr> ConnectionMap;
    ConnectionMap connMap_;

    EpollCallback onConnectionCb_;
    EpollCallback onMessageCb_;
    EpollCallback onCloseCb_;
};

} // end of namespace wd
